package com.lv.common.base

import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.CallSuper
import androidx.annotation.ColorRes
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.LogUtils
import com.lv.common.R
import com.lv.common.imp.OnPositionTListener
import com.lv.common.ktx.bindView
import com.lv.common.ktx.viewLifeCycleOwner
import com.lv.common.lce.DefaultLceImpl
import com.lv.common.lce.ILce
import com.lv.common.utils.StatusBarUtil
import com.lv.common.utils.showToast
import me.jessyan.autosize.internal.CustomAdapt
import java.lang.ref.WeakReference

/**
 * 作者： ygx
 * 创建日期：2022/1/20 9:19 PM
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 *      _              _           _     _   ____  _             _ _
 *     / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 *    / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 *   / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 *  /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 *
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * 简单封装的基类Activity
 */
abstract class BaseActivity<ActBinding : ViewDataBinding> : AppCompatActivity, ILce, CustomAdapt {
    /**
     * 无参构造函数
     */
    constructor() : super()

    /**
     * 可以填入layout布局的构造函数，使用viewBinding的方便
     * [layout] layout布局文件的id
     */
    constructor(@LayoutRes layout: Int) : super(layout)

    protected lateinit var mBinding: ActBinding


    /**
     * Activity中显示加载等待的控件。
     */
    private var loading: View? = null

    /**
     * Activity中由于服务器异常导致加载失败显示的布局。
     */
    private var loadErrorView: View? = null

    /**
     * Activity中由于网络异常导致加载失败显示的布局。
     */
    private var badNetworkView: View? = null

    /**
     * Activity中当界面上没有任何内容时展示的布局。
     */
    private var noContentView: View? = null

    private var defaultLce: ILce? = null

    private var weakRefActivity: WeakReference<Activity>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = bindView<ActBinding>(getLayoutRes()).also {
            it.lifecycleOwner = viewLifeCycleOwner
        }
        BarUtils.transparentStatusBar(this)
        setupViews()
        ActivityCollector.add(WeakReference(this))
        weakRefActivity = WeakReference(this)
        initView()
        initConfig()
        initData()
        initEvents()
    }

    protected open fun isHaveHeadMargin(): Boolean {
        return false
    }

    protected open fun setupViews() {
        val view = View.inflate(this, R.layout.layout_lce, null)
        val params = FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT
        )
        val isPort = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT

        params.setMargins(
            0,
            if (isHaveHeadMargin()) {
                ConvertUtils.dp2px(if (isPort) 70f else 55f)
            } else 0, 0,
            0
        )
        addContentView(view, params)
        loading = view.findViewById(R.id.loading)
        noContentView = view.findViewById(R.id.noContentView)
        badNetworkView = view.findViewById(R.id.badNetworkView)
        loadErrorView = view.findViewById(R.id.loadErrorView)
        if (loading == null) {
            LogUtils.e("loading is null")
        }
        if (badNetworkView == null) {
            LogUtils.e("badNetworkView is null")
        }
        if (loadErrorView == null) {
            LogUtils.e("loadErrorView is null")
        }
        defaultLce = DefaultLceImpl(
            loading,
            loadErrorView,
            badNetworkView,
            noContentView
        )
        loadFinished()
    }

    @LayoutRes
    abstract fun getLayoutRes(): Int

    /**
     * 必要的view初始化
     */
    open fun initView() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initView")
    }

    /**
     * 必要的配置初始化
     */
    open fun initConfig() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initConfig")
    }

    /**
     * 必要的数据初始化
     */
    open fun initData() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initData")
    }

    /**
     * view初始化后的事件处理
     */
    open fun initEvents() {
//        LogUtils.d("${this.javaClass.simpleName} 初始化 initConfig")
    }

    override fun onDestroy() {
        super.onDestroy()
        if (this::mBinding.isInitialized) {
            mBinding.unbind()
        }
        ActivityCollector.remove(weakRefActivity)

    }

    /**
     * 扩展用于liveData便捷写法的函数
     * [block]liveData对象，响应change变化的逻辑块
     */
    protected inline fun <T : Any> LiveData<T>.observeKt(crossinline block: (T?) -> Unit) {
        this.observe(this@BaseActivity, Observer {
            block(it)
        })
    }

    open fun initStatusBar(
        mContext: Activity,
        isImmersive: Boolean,
        isBlackFont: Boolean,
        @ColorRes toolbarColor: Int = R.color.colorWhite,
        alpha: Float = 1.0f
    ) {
        //沉浸式实现
        if (isImmersive) {
            StatusBarUtil.immersive(mContext)
        } else {
            //状态栏颜色  activity  color(状态栏颜色值) alpha（透明度，取值范围 0.0f - 1.0f ）
            StatusBarUtil.darkMode(mContext, resources.getColor(toolbarColor), alpha)
        }

        //填充View id：控件id
//        StatusBarUtil.setPaddingSmart(this, id)

        //状态栏字体颜色  true：黑色  false：白色
        StatusBarUtil.darkMode(mContext, isBlackFont)


    }

    //点击空白地方隐藏软键盘
    open fun hideKeyboard(
        event: MotionEvent, view: View?,
        activity: Activity
    ) {
        try {
            if (view != null && view is EditText) {
                val location = intArrayOf(0, 0)
                view.getLocationInWindow(location)
                val left = location[0]
                val top = location[1]
                val right = (left
                        + view.getWidth())
                val bootom = top + view.getHeight()
                // 判断焦点位置坐标是否在空间内，如果位置在控件外，则隐藏键盘
                if (event.rawX < left || event.rawX > right || event.y < top || event.rawY > bootom
                ) {
                    // 隐藏键盘
                    val token = view.getWindowToken()
                    val inputMethodManager = activity
                        .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    inputMethodManager.hideSoftInputFromWindow(
                        token, InputMethodManager.HIDE_NOT_ALWAYS
                    )
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                val view: View? = currentFocus
                hideKeyboard(ev, view, this) //调用方法判断是否需要隐藏键盘
            }
            else -> {
            }
        }
        return super.dispatchTouchEvent(ev)
    }

//    override fun getResources(): Resources? {
//        val res = super.getResources()
//        runOnUiThread {
//            AutoSizeCompat.autoConvertDensityOfGlobal(res) //如果没有自定义需求用这个方法
//        }
//        var config = res.configuration
//        if (config.fontScale == 1f) return res
//        config = Configuration()
//        config.setToDefaults()
//        res.updateConfiguration(config, res.displayMetrics)
//        return res
//    }

    override fun isBaseOnWidth(): Boolean {
        return true
    }

    override fun getSizeInDp(): Float {
        return 360.0f
    }

    protected open fun isSearchPage(): Boolean {
        return false
    }

    /**
     * 设置 LiveData 的状态，根据不同状态显示不同页面
     *
     * @param dataLiveData LiveData
     * @param onDataStatus 数据回调进行使用
     */
    fun <T> setDataStatus(dataLiveData: LiveData<Result<T>>, onDataStatus: (T) -> Unit) {
        dataLiveData.observe(this) {
            if (it.isSuccess) {
                val dataList = it.getOrNull()
                if (dataList != null) {
                    loadFinished()
                    onDataStatus(dataList)
                } else {
                    showLoadErrorView()
                }
            } else {
                showToast(getString(R.string.bad_network_view_tip))
                showBadNetworkView { initData() }
            }
        }
    }

    @CallSuper
    override fun startLoading(tip: String, boolean: Boolean) {
        defaultLce?.startLoading(tip, boolean)
    }

    @CallSuper
    override fun loadFinished() {
        defaultLce?.loadFinished()
    }

    override fun showLoadErrorView(
        tip: String,resouse: Int,
        showBack: Boolean,
        callback: View.OnClickListener?
    ) {
        defaultLce?.showLoadErrorView(tip,resouse,showBack,callback)
    }

    override fun showBadNetworkView(listener: View.OnClickListener) {
        defaultLce?.showBadNetworkView(listener)
    }

    override fun showNoContentView(tip: String) {
        defaultLce?.showNoContentView(tip)
    }

    fun getEmptyView(
        rvContent: RecyclerView,
        tip: String = "暂无信息",
        empty: Int = R.drawable.icon_empty,
        isShowLogin: Boolean = false,
        mLayout:Int=R.layout.empty_view
    ): View {
        val view: View = layoutInflater.inflate(mLayout, rvContent, false)
        val ivImg = view.findViewById<ImageView>(R.id.iv_img)
        val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
        ivImg.setImageResource(empty)
        tvEmpty.text = tip

        return view
    }

    fun getEmptyCenterView(
        rvContent: RecyclerView,
        tip: String = "暂无信息",
        empty: Int = R.drawable.icon_empty,
        isShowLogin: Boolean = false
    ): View {
        val view: View = layoutInflater.inflate(R.layout.empty_center_view, rvContent, false)
        val ivImg = view.findViewById<ImageView>(R.id.iv_img)
        val tvEmpty = view.findViewById<TextView>(R.id.tv_empty)
        ivImg.setImageResource(empty)
        tvEmpty.text = tip

        return view
    }
}